﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Diagnostics;
using Ude;

namespace QuickPasteItLib
{
    public class FileTools
    {
        /// <summary>
        /// Gets the paste language from the given file extension.
        /// </summary>
        /// <param name="extension">The file extension to get the paste language for.</param>
        /// <returns>The PasteLang matching the given file extension.</returns>
        public static PasteLang GetPasteLangFromExtension(string extension)
        {
            var extensionMap = new Dictionary<string, PasteLang>
            {
                {"sh", PasteLang.Bash},
                {"bash", PasteLang.Bash},
                {"bat", PasteLang.Batch},
                {"c", PasteLang.C},
                {"cpp", PasteLang.Cpp},
                {"h", PasteLang.Cpp},
                {"cs", PasteLang.CSharp},
                {"css", PasteLang.CSS},
                {"coffee", PasteLang.CoffeeScript},
                {"fs", PasteLang.FSharp},
                {"fsi", PasteLang.FSharp},
                {"hs", PasteLang.Haskell},
                {"htm", PasteLang.HTML},
                {"html", PasteLang.HTML},
                {"ini", PasteLang.Ini},
                {"cfg", PasteLang.Ini},
                {"java", PasteLang.Java},
                {"js", PasteLang.JavaScript},
                {"json", PasteLang.JavaScript},
                {"pl", PasteLang.Perl},
                {"pm", PasteLang.Perl},
                {"php5", PasteLang.PHP},
                {"php", PasteLang.PHP},
                {"txt", PasteLang.Plain},
                {"py", PasteLang.Python},
                {"rb", PasteLang.Ruby},
                {"sql", PasteLang.SQL},
                {"tex", PasteLang.Tex},
                {"vb", PasteLang.VB},
                {"xml", PasteLang.XML},
                {"rss", PasteLang.XML},
                {"atom", PasteLang.XML},
                {"csproj", PasteLang.XML},
                {"sln", PasteLang.XML},
                {"vbproj", PasteLang.XML},
                {"resx", PasteLang.XML},
                {"yaml", PasteLang.YAML},
                {"yml", PasteLang.YAML}
            };

            extension = extension.ToLower().Trim().TrimStart('.');

            if (extensionMap.ContainsKey(extension))
                return extensionMap[extension];
            else
                return PasteLang.Plain;
        }

        /// <summary>
        /// Detects the encoding of the given text file.
        /// </summary>
        /// <param name="file">The file.</param>
        /// <returns>The encoding used in the file.</returns>
        public static Encoding DetectFileEncoding(FileInfo file)
        {
            try
            {
                ICharsetDetector cdet = new CharsetDetector();
                cdet.Feed(file.OpenRead());
                cdet.DataEnd();
                return Encoding.GetEncoding(cdet.Charset);
            }
            catch
            {
                return null;
            }
        }

        /// <summary>
        /// Checks for any null bytes in the given file
        /// </summary>
        /// <param name="fs">The file to check for null bytes.</param>
        /// <returns>True if null bytes found, false otherwise.</returns>
        public static bool FileHasNullBytes(FileInfo file)
        {
            FileStream fs = file.OpenRead();
            for (int i = 0; i < fs.Length; i++)
            {
                if (fs.ReadByte() == 0)
                    return true;
            }
            return false;
        }
    }
}
